package cn.jingyuan.bee.utils.convert.impl;

import cn.jingyuan.bee.utils.StringUtils;
import cn.jingyuan.bee.utils.TypeUtils;
import cn.jingyuan.bee.utils.convert.AbstractConverter;
import cn.jingyuan.bee.utils.convert.ConverterRegistry;

import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Type;

/**
 * {@link Reference} 转换器
 */
public class ReferenceConverter extends AbstractConverter<Reference> {

    private final Class<? extends Reference> targetType;

    /**
     * 构造
     *
     * @param targetType {@link Reference} 实现类型
     */
    public ReferenceConverter(Class<? extends Reference> targetType) {
        this.targetType = targetType;
    }

    @Override
    protected Reference<?> convertInternal(Object value) {
        // 尝试将值转换为 Reference 泛型的类型
        Object targetValue = null;
        final Type paramType = TypeUtils.getTypeArgument(targetType);
        if (!TypeUtils.isUnknown(paramType)) {
            targetValue = ConverterRegistry.getInstance().convert(paramType, value);
        }
        if (null == targetValue) {
            targetValue = value;
        }

        if (this.targetType == WeakReference.class) {
            return new WeakReference(targetValue);
        } else if (this.targetType == SoftReference.class) {
            return new SoftReference(targetValue);
        }

        throw new UnsupportedOperationException(StringUtils.format("unsupported reference type: {}", this.targetType.getName()));
    }

}
